package com.yifeng.repo.flink.data.transport.streaming.connectors.oracle.antlr.listener;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.yifeng.repo.flink.data.transport.dto.DdlTypeEnums;

import io.debezium.ddl.parser.oracle.generated.PlSqlParser;

/**
 * DDL解析
 * @author lijing
 * @since 2023-04-12
 *
 */
public class OracleDdlParserListener extends OracleBaseParserListener {

	private static final Logger LOGGER = LoggerFactory.getLogger(OracleDdlParserListener.class);

    /**
     * 表名
     */
    private String tableName;
    
	/**
	 * key: ddl变更的类型
	 * Map : rename的前后字段名称，key为老名称, value为新名称
	 */
	private Map<String, Map<String,String>> renameMap;
	
	/**
	 * key: ddl变更的类型
	 * value: alter table 新增、修改、删除的字段
	 */
	private Map<String, List<String>> columnMap;

	public OracleDdlParserListener(String tableName) {
		super();
		this.tableName = tableName;
		this.columnMap = new HashMap<String, List<String>>();
		this.renameMap = new HashMap<String, Map<String,String>>();
	}

	@Override
	public void enterAdd_column_clause(PlSqlParser.Add_column_clauseContext ctx) {
		List<PlSqlParser.Column_definitionContext> columns = ctx.column_definition();
		List<String> columnList = new ArrayList<String>();
		for (PlSqlParser.Column_definitionContext column : columns) {
			String columnName = getColumnName(column.column_name());
			columnList.add(columnName);
		}
		if(columnMap.get(DdlTypeEnums.ADD.getType()) != null) {
			columnList.addAll(columnMap.get(DdlTypeEnums.ADD.getType()));
		}
		columnMap.put(DdlTypeEnums.ADD.getType(), columnList);
		super.enterAdd_column_clause(ctx);
	}

	@Override
	public void enterModify_column_clauses(PlSqlParser.Modify_column_clausesContext ctx) {
		List<PlSqlParser.Modify_col_propertiesContext> columns = ctx.modify_col_properties();
		List<String> columnList = new ArrayList<String>();
		for (PlSqlParser.Modify_col_propertiesContext column : columns) {
			String columnName = getColumnName(column.column_name());
			columnList.add(columnName);
		}
		if(columnMap.get(DdlTypeEnums.MODIFY.getType()) != null) {
			columnList.addAll(columnMap.get(DdlTypeEnums.MODIFY.getType()));
		}
		columnMap.put(DdlTypeEnums.MODIFY.getType(), columnList);
		super.enterModify_column_clauses(ctx);
	}

	@Override
	public void enterDrop_column_clause(PlSqlParser.Drop_column_clauseContext ctx) {
		List<PlSqlParser.Column_nameContext> columnNameContexts = ctx.column_name();
		List<String> columnList = new ArrayList<String>();
		for (PlSqlParser.Column_nameContext columnNameContext : columnNameContexts) {
			String columnName = getColumnName(columnNameContext);
			columnList.add(columnName);
		}
		if(columnMap.get(DdlTypeEnums.DROP.getType()) != null) {
			columnList.addAll(columnMap.get(DdlTypeEnums.DROP.getType()));
		}
		columnMap.put(DdlTypeEnums.DROP.getType(), columnList);
		super.enterDrop_column_clause(ctx);
	}

	@Override
	public void enterRename_column_clause(PlSqlParser.Rename_column_clauseContext ctx) {
		Map<String,String> map = new HashMap<String,String>();
		map.put(getColumnName(ctx.old_column_name()), getColumnName(ctx.new_column_name()));
		if(renameMap.get(DdlTypeEnums.RENAME_COLUMN.getType()) != null) {
			map.putAll(renameMap.get(DdlTypeEnums.RENAME_COLUMN.getType()));
		}
		renameMap.put(DdlTypeEnums.RENAME_COLUMN.getType(), map);
		super.enterRename_column_clause(ctx);
	}
	
	@Override
    public void enterAlter_table_properties(PlSqlParser.Alter_table_propertiesContext ctx) {
		if (ctx.RENAME() != null && ctx.TO() != null) {
            Map<String,String> map = new HashMap<String,String>();
    		map.put(tableName, getTableName(ctx.tableview_name()));
    		renameMap.put(DdlTypeEnums.RENAME_TABLE.getType(), map);
        }
        super.exitAlter_table_properties(ctx);
    }

	public Map<String, Map<String, String>> getRenameMap() {
		return renameMap;
	}

	public void setRenameMap(Map<String, Map<String, String>> renameMap) {
		this.renameMap = renameMap;
	}

	public Map<String, List<String>> getColumnMap() {
		return columnMap;
	}

	public void setColumnMap(Map<String, List<String>> columnMap) {
		this.columnMap = columnMap;
	}
	
}
